package com.test.month_2020_04.day_03;

import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class T06_001_CompletableFuture {
    /*public static void main(String[] args) throws Exception {
        CompletableFuture<String> future
                = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
            }

            return "Hello ";
        }).thenCompose(s -> CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
            }

            return s + "World";
        }));

        System.out.println(future.get()); // Hello World
    }*/

    /**
     * 有时候我们可能需要等待所有的异步任务都执行完毕，然后组合他们的结果。我们可以使用 allOf() 方法：
     * @param args
     * @throws Exception
     */
    /*public static void main(String[] args) throws Exception {
        CompletableFuture<String> future1
                = CompletableFuture.supplyAsync(() -> "Hello");
        CompletableFuture<String> future2
                = CompletableFuture.supplyAsync(() -> "World");


        CompletableFuture<Void> combinedFuture
                = CompletableFuture.allOf(future1, future2);

        // 这个方法不会合并结果，可以看到他的返回值是 Void 类型
        combinedFuture.get();

        // 我们需要手动来处理每一个并行异步任务的结果
        String combined = Stream.of(future1, future2)
                .map(CompletableFuture::join)
                .collect(Collectors.joining(" "));

        System.out.println(combined); // Hello World
    }*/

    /**
     * 有时候我们可能不需要等待所有的异步任务都执行完毕，只要任何一个任务完成就返回结果。我们可以使用 anyOf() 方法：
     * @param args
     * @throws Exception
     */
    /*public static void main(String[] args) throws Exception {
        CompletableFuture<String> future1
                = CompletableFuture.supplyAsync(() -> "Hello");
        CompletableFuture<String> future2
                = CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(2000);
                    } catch (Exception e) {
                    }

                    return "World";
                }
        );


        CompletableFuture<Object> combinedFuture
                = CompletableFuture.anyOf(future1, future2);

        System.out.println(combinedFuture.get()); // Hello
    }*/

    /**
     * 异常的处理
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        String name = null;

        CompletableFuture<String> future
                = CompletableFuture.supplyAsync(() -> {
            if (name == null) {
                throw new RuntimeException("Computation error!");
            }

            return "Hello, " + name;
        }).handle((s, t) -> s != null ? s : "Hello, Stranger!");

        System.out.println(future.get()); // Hello, Stranger!
    }
}